package com.geely.club.util;

import android.util.Log;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by mengyangyang on 2015-10-15.
 */
public class HttpUtil {
    private final static String TAG = HttpUtil.class.getName();
    private static List<Cookie> cookieList;

    public interface GetCallBack {
        int STATUS_SUCCESS = -1;
        int STATUS_CONNECTED_FAILED = -2;
        int STATUS_SERVER_ERROR = -3;

        void callBack(String string, int statusCode);
    }

    public interface DownloadCallBack {
        int STATUS_SUCCESS = -1;
        int STATUS_CONNECTED_FAILED = -2;
        int STATUS_SERVER_ERROR = -3;

        void callBack(File file, int statusCode);

        /**
         * @param progress 下载进度 0~100
         * @param sum      要下载的文件大小 单位byte
         */
        void onDownload(int progress, int sum);
    }

    /**
     * @param url
     * @return
     */
    public static String doGet(String url) {
        return doGet(url, null);
    }

    /**
     * @param url
     * @param map 可以为null
     * @return
     */
    public static String doGet(String url, HashMap<String, String> map) {
        String result = null;
        if (null != map) {
            url += "?";
            for (Map.Entry<String, String> entry : map.entrySet()) {
                url += entry.getKey() + '=' + entry.getValue() + '&';
            }
        }
        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet get = new HttpGet(url);
            if (null != cookieList) {
                StringBuilder sb = new StringBuilder();
                for (Cookie cookie : cookieList) {
                    sb.append(cookie.getName());
                    sb.append("=");
                    sb.append(cookie.getValue());
                    sb.append(";");
                }
                get.addHeader("cookie", sb.toString());
            }
            HttpResponse response = httpClient.execute(get);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                if (null != entity) {
                    result = EntityUtils.toString(entity, "UTF-8");
                    cookieList = httpClient.getCookieStore().getCookies();
                }
            } else {
                Log.e(TAG, response.getStatusLine().toString());
            }
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return result;
    }

    public static void doGetAsync(final String url) {
        doGetAsync(url, null);
    }

    public static void doGetAsync(final String url, final HashMap<String, String> map) {
        doGetAsync(url, map, new GetCallBack() {
            @Override
            public void callBack(String string, int statusCode) {

            }
        });
    }

    public static void doGetAsync(final String url, final HashMap<String, String> map, final GetCallBack callBack) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                StringBuilder sb = new StringBuilder();
                String result = null;
                sb.append(url);
                sb.append("?");
                if (null != map) {
                    for (Map.Entry<String, String> entry : map.entrySet()) {
                        sb.append(entry.getKey());
                        sb.append('=');
                        sb.append(entry.getValue());
                        sb.append('&');
                    }
                }
                try {
                    HttpClient httpClient = new DefaultHttpClient();
                    HttpGet get = new HttpGet(sb.toString());
                    HttpResponse response = httpClient.execute(get);
                    if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                        HttpEntity entity = response.getEntity();
                        if (null != entity) {
                            result = EntityUtils.toString(entity, "UTF-8");
                            callBack.callBack(result, GetCallBack.STATUS_SUCCESS);
                        }
                    } else {
                        callBack.callBack(null, GetCallBack.STATUS_SERVER_ERROR);
                        Log.e(TAG, "URL:" + url + "\nSERVER:" + response.getStatusLine().toString());
                    }
                } catch (IOException e) {
                    callBack.callBack(null, GetCallBack.STATUS_CONNECTED_FAILED);
                    Log.e(TAG, e.toString());
                }
            }
        }).start();
    }

    public static void downloadAsync(final String url, final String filePath, final DownloadCallBack callBack) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                File tmpFile = new File(filePath + ".tmp");
                try {
                    URL u = new URL(url);
                    HttpURLConnection connection = (HttpURLConnection) u.openConnection();
                    BufferedInputStream bis = new BufferedInputStream(connection.getInputStream(), 1024);
                    int sum = connection.getContentLength();
                    int received = 0;
                    FileOutputStream fos = new FileOutputStream(tmpFile);
                    byte[] buffer = new byte[1024];
                    int n = 0;
                    do {
                        received += n;
                        fos.write(buffer, 0, n);
                        callBack.onDownload(received * 100 / sum, sum);
                        n = bis.read(buffer);
                    } while (n != -1);
                    fos.close();
                    tmpFile.renameTo(new File(filePath));
                    callBack.onDownload(100, sum);
                    callBack.callBack(new File(filePath), DownloadCallBack.STATUS_SUCCESS);
                    connection.disconnect();
                } catch (MalformedURLException e) {
                    Log.e(TAG, e.toString());
                } catch (IOException e) {
                    callBack.callBack(null, GetCallBack.STATUS_CONNECTED_FAILED);
                    tmpFile.delete();
                    Log.e(TAG, e.toString());
                }
            }
        });
        thread.setName("Downloading-File");
        thread.setPriority(Thread.MIN_PRIORITY);
        thread.start();
    }

    public static boolean download(String url, String filePath) {
        boolean isSucceed = false;
        try {
            URL u = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) u.openConnection();
            BufferedInputStream bis = new BufferedInputStream(connection.getInputStream(), 1024);
            FileOutputStream fos = new FileOutputStream(filePath);
            byte[] buffer = new byte[1024];
            int n = 0;
            do {
                n = bis.read(buffer);
                fos.write(buffer, 0, n);
            } while (n != 1);
            fos.close();
            isSucceed = true;
            connection.disconnect();
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException(e.toString());
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }
        return isSucceed;
    }


}
